package com.bandaotixi.cashier.api.system.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.crypto.digest.BCrypt;
import com.bandaotixi.cashier.api.common.constant.SystemConstants;
import com.bandaotixi.cashier.api.common.exception.BusinessException;
import com.bandaotixi.cashier.api.common.model.KeyValue;
import com.bandaotixi.cashier.api.core.mybatis.SqlUtil;
import com.bandaotixi.cashier.api.system.mapper.UserMapper;
import com.bandaotixi.cashier.api.system.model.entity.User;
import com.bandaotixi.cashier.api.system.model.form.PasswordUpdateForm;
import com.bandaotixi.cashier.api.system.model.form.UserForm;
import com.bandaotixi.cashier.api.system.model.vo.CurrentUserVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.base.MPJBaseServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class UserService extends MPJBaseServiceImpl<UserMapper, User> {

    public boolean saveUser(UserForm userForm) {

        String username = userForm.getUsername();

        long count = this.count(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        Assert.isTrue(count == 0, "用户名已存在");

        // 实体转换 form->entity
        User entity = new User();
        BeanUtils.copyProperties(userForm, entity);

        // 设置默认加密密码
        String defaultEncryptPwd = BCrypt.hashpw(SystemConstants.DEFAULT_PASSWORD, BCrypt.gensalt());
        entity.setPassword(defaultEncryptPwd);

        // 新增用户
        boolean result = this.save(entity);

        if (result) {
            // 删除用户角色
            SqlUtil.delete("sys_user_role", Map.of("user_id", entity.getId()));
            // 保存用户角色
            SqlUtil.relationalBatchUpsert("sys_user_role", "user_id", "role_id", userForm.getRoleIds().stream().map(roleId -> new KeyValue<>(entity.getId(), roleId)).toList());
        }
        return result;
    }

    public CurrentUserVO getCurrentUser() {
        // 获取登录用户基础信息
        User user = this.lambdaQuery()
                .eq(User::getId, StpUtil.getLoginId())
                .select(
                        User::getId,
                        User::getUsername,
                        User::getNickname,
                        User::getAvatar
                )
                .oneOpt()
                .orElseThrow(() -> new BusinessException("用户不存在"));

        CurrentUserVO currentUser = new CurrentUserVO();
        BeanUtils.copyProperties(user, currentUser);

        // 用户角色集合
        List<String> roles = StpUtil.getRoleList();
        currentUser.setRoles(roles);

        // 用户权限集合
        if (CollectionUtil.isNotEmpty(roles)) {
            currentUser.setPerms(StpUtil.getPermissionList());
        }
        return currentUser;
    }

    public boolean changePassword(Long userId, PasswordUpdateForm data) {

        User user = this.getById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        String oldPassword = data.getOldPassword();
        // 校验原密码
        if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
            throw new BusinessException("原密码错误");
        }
        // 新旧密码不能相同
        if (BCrypt.checkpw(data.getNewPassword(), user.getPassword())) {
            throw new BusinessException("新密码不能与原密码相同");
        }

        String newPassword = data.getNewPassword();
        boolean result = this.update(new LambdaUpdateWrapper<User>()
                .eq(User::getId, userId)
                .set(User::getPassword, BCrypt.hashpw(newPassword, BCrypt.gensalt()))
        );

        if (result) {
            // 加入黑名单，重新登录
            StpUtil.logout();
        }
        return result;
    }

}




